<?php

namespace app\event;

use app\admin\cache\AdminCache;
use app\admin\model\Admin;

class Permission
{
    // ===== 管理员相关 =====

    /**
     * 管理员授权角色后刷新该管理员缓存
     * @param array $payload ['adminId' => int]
     * @return void
     */
    public function adminRolesGranted(array $payload): void
    {
        if (empty($payload['adminId'])) {
            return;
        }
        $admin = Admin::with([
            'roles' => function ($query) {
                $query->with([
                    'menus' => function ($query) {
                        $query->where('status', 1)->orderBy('sort', 'asc');
                    },
                ]);
            },
        ])->find($payload['adminId']);
        if ($admin) {
            AdminCache::refreshAllCache($admin);
        }
    }

    /**
     * 管理员状态变更后刷新或清理缓存
     * @param array $payload ['adminId' => int, 'status' => int]
     * @return void
     */
    public function adminStatusChanged(array $payload): void
    {
        if (empty($payload['adminId']) || $payload['status'] === null) {
            return;
        }
        if ((int)$payload['status'] === 1) {
            $admin = Admin::with([
                'roles' => function ($query) {
                    $query->with([
                        'menus' => function ($query) {
                            $query->where('status', 1)->orderBy('sort', 'asc');
                        },
                    ]);
                },
            ])->find($payload['adminId']);
            if ($admin) {
                AdminCache::refreshAllCache($admin);
            }
        } else {
            AdminCache::clearAllCache($payload['adminId']);
        }
    }

    /**
     * 管理员删除后清理其缓存
     * @param array $payload ['adminId' => int]
     * @return void
     */
    public function adminDeleted(array $payload): void
    {
        if (!empty($payload['adminId'])) {
            AdminCache::clearAllCache($payload['adminId']);
        }
    }

    // ===== 角色相关 =====

    /**
     * 角色授权菜单后刷新该角色下所有管理员缓存
     * @param array $payload ['roleId' => int]
     * @return void
     */
    public function roleMenusGranted(array $payload): void
    {
        if (empty($payload['roleId'])) {
            return;
        }
        $admins = Admin::with([
            'roles' => function ($query) {
                $query->with([
                    'menus' => function ($query) {
                        $query->where('status', 1)->orderBy('sort', 'asc');
                    },
                ]);
            },
        ])->whereHas('roles', function ($query) use ($payload) {
            $query->where('id', $payload['roleId']);
        })->get();
        foreach ($admins as $admin) {
            AdminCache::refreshAllCache($admin);
        }
    }

    /**
     * 角色更新后刷新该角色下所有管理员缓存
     * @param array $payload ['roleId' => int]
     * @return void
     */
    public function roleUpdated(array $payload): void
    {
        if (empty($payload['roleId'])) {
            return;
        }
        $admins = Admin::with([
            'roles' => function ($query) {
                $query->with([
                    'menus' => function ($query) {
                        $query->where('status', 1)->orderBy('sort', 'asc');
                    },
                ]);
            },
        ])->whereHas('roles', function ($query) use ($payload) {
            $query->where('id', $payload['roleId']);
        })->get();
        foreach ($admins as $admin) {
            AdminCache::refreshAllCache($admin);
        }
    }

    /**
     * 角色删除后刷新该角色下所有管理员缓存
     * @param array $payload ['roleId' => int]
     * @return void
     */
    public function roleDeleted(array $payload): void
    {
        if (empty($payload['roleId'])) {
            return;
        }
        $admins = Admin::with([
            'roles' => function ($query) {
                $query->with([
                    'menus' => function ($query) {
                        $query->where('status', 1)->orderBy('sort', 'asc');
                    },
                ]);
            },
        ])->whereHas('roles', function ($query) use ($payload) {
            $query->where('id', $payload['roleId']);
        })->get();
        foreach ($admins as $admin) {
            AdminCache::refreshAllCache($admin);
        }
    }

    // ===== 菜单相关 =====

    /**
     * 菜单更新后刷新受影响管理员缓存
     * @param array $payload ['menuId' => int]
     * @return void
     */
    public function menuUpdated(array $payload): void
    {
        if (empty($payload['menuId'])) {
            return;
        }
        $admins = Admin::with([
            'roles' => function ($query) {
                $query->with([
                    'menus' => function ($query) {
                        $query->where('status', 1)->orderBy('sort', 'asc');
                    },
                ]);
            },
        ])->whereHas('roles', function ($query) use ($payload) {
            $query->whereHas('menus', function ($q) use ($payload) {
                $q->where('id', $payload['menuId']);
            });
        })->get();
        foreach ($admins as $admin) {
            AdminCache::refreshAllCache($admin);
        }
    }

    /**
     * 菜单删除后刷新受影响管理员缓存
     * @param array $payload ['menuId' => int]
     * @return void
     */
    public function menuDeleted(array $payload): void
    {
        if (empty($payload['menuId'])) {
            return;
        }
        $admins = Admin::with([
            'roles' => function ($query) {
                $query->with([
                    'menus' => function ($query) {
                        $query->where('status', 1)->orderBy('sort', 'asc');
                    },
                ]);
            },
        ])->whereHas('roles', function ($query) use ($payload) {
            $query->whereHas('menus', function ($q) use ($payload) {
                $q->where('id', $payload['menuId']);
            });
        })->get();
        foreach ($admins as $admin) {
            AdminCache::refreshAllCache($admin);
        }
    }
}